#include "../include/lecteur.hpp"

using namespace std;
FileManager * FileManager::_me = NULL;
//const char* Box::nomMnt = "bassin.bin";
//const char* Box::nomMnt ="bassins/mnt100_sb50.bin";
const char* Box::nomMnt ="bassins/MNT50m.bin";
const char* Box::nomPt = "bassin.pt";
const char* Box::nomTmp = "tmp";
int Box::cpt=0;

FileManager::FileManager()
{
    _me = this;
    _lignes=0;
    _nblig=0;
    _nbcol=0;
    fichiersource = new std::ifstream("bassin.bin", std::ifstream::in | std::ifstream::binary);
    lolilol tip;
    fichiersource->read((char*)&tip, sizeof(tip));
    _nblig=tip.b;
    _nbcol=tip.a;
    _novalue=tip.f;
}

bool FileManager::getLine(int *tab, unsigned int line, const char * fic)
{
    //on ouvre en lecture seule
    ifstream fichier(fic, ifstream::in | std::ifstream::binary);

    //verifie si le fichier demande a ete trouve
    if(fichier)
    {
        unsigned int cols,rows;
        lolilol tip;
        fichier.read((char*)&tip, sizeof(tip));
        cols = tip.a; rows=tip.b;

        //verifie si on ne demande pas une ligne exterieure au fichier
        if(rows > line)
        {
            //on se place a la bonne ligne dans le mnt
            for(unsigned int i = 0; i < line; i++)
                fichier.read((char*)&tab[0], _nbcol * sizeof(int));

            //on stocke les donnees du fichier dans le tableau resultat
            fichier.read((char*)&tab[0], _nbcol * sizeof(int));

            fichier.close();
            return true;
        }
        //la ligne demandee nest pas valide
        else
        {
            cout<<"ligne non presente dans le fichier"<<endl;
        }
        fichier.close();
    }
    //en cas dechec douverture du fichier
    else
        cout<<"echec de lecture"<<endl;
    return false;
}

bool FileManager::addLine(int *tab)
{

    //on ouvre en lecture ecriture en fin de fichier
    fstream fichier(Box::nomPt, ios::in | ios::out | ios::ate |std::ifstream::binary);
    //verifie si le fichier demande a ete trouve
    if(fichier)
    {
        fichier.write((char*)&tab[0], _nbcol * sizeof(int));
        _lignes++;
        fichier.close();
        return true;
    }
    //en cas dechec douverture du fichier
    else
        cout<<"echec de lecture"<<endl;
    return false;
}

bool FileManager::switchVal(std::map<int, int> mymap)
{
    ifstream fichier(Box::nomPt, ifstream::in| std::ifstream::binary);
    if(fichier)
    {
        //Si nous sommes sous Windows
        //#if defined (WIN32)
        system("copy nul tmp");
        // Sinon, si nous sommes sous Linux
      /*  #elif defined (linux)
            cout<<"A IMPLEMENTER POUR LINUX"<<endl;
        #endif*/
        fstream fichiertmp(Box::nomTmp, ios::in | ios::out| std::ifstream::binary);
        if(fichiertmp)
        {
            lolilol tip;
            tip.a=0; tip.b=0;
            fichier.read((char*)&tip, sizeof(tip));
            fichiertmp.write((char*)&tip , sizeof(tip));

            map<int,int>::iterator it;
            int tab2[_nbcol];

            for(unsigned int i = 0; i < tip.b and !fichier.eof(); i++)
            {
                fichier.read((char*)&tab2, _nbcol * sizeof(int));
                for(unsigned int j = 0; j < tip.a; j++)
                {

                    it=mymap.find(tab2[j]);
                    if(it!= mymap.end())
                    {
                        tab2[j] = mymap[tab2[j]];
                    }
                }fichiertmp.write((char*)&tab2[0] , _nbcol * sizeof(int));
            }
            fichier.close();
            fichiertmp.close();
            //Si nous sommes sous Windows
            //#if defined (WIN32)
                string cmd = "del " + (string)Box::nomPt;
                system(cmd.c_str());
                cmd="rename tmp "+(string)Box::nomPt;
                system(cmd.c_str());
            // Sinon, si nous sommes sous Linux
            /*#elif defined (linux)
                cout<<"A IMPLEMENTER POUR LINUX"<<endl;
            #endif*/
            return true;
        }
        else
        cout<<"echec decriture lol"<<endl;
    }
    //en cas dechec douverture du fichier
    else
        cout<<"echec de lecture"<<endl;
    return false;
}


void FileManager::translate(bool b, string binary, string mnt)
{

    FILE * fichier;
    int a,x,y;
    string str1 = "rb";
    if(b)
    {
        ifstream fichier(binary.c_str(), ios::in| std::ifstream::binary);
        string lol = "copy nul " + mnt;
        system(lol.c_str());

        fstream fichierb(mnt.c_str() , ios::in | ios::out);
        if(fichier)
        {
            if(fichierb.is_open())
            {
                fichier.read((char*)&x,sizeof(int));
                fichier.read((char*)&y,sizeof(int));
                x=2000;y=2000;
                fichierb<<x<<endl;
                fichierb<<y<<endl;
                cout<<x<<" "<<y<<endl;
                for(int i = 0; i < 4; i++)
                {
                    a = 0;
                    fichier.read((char*)&a,sizeof(int));
                    fichierb<<a<<endl;
                }
                for(int i = 0; i < x; i++)
                {
                    for(int j = 0; j < y; j++)
                    {
                        a = 0;
                        fichier.read((char*)&a,sizeof(int));
                        fichierb<<a;
                        if(j!=(y-1)){fichierb<<" ";}
                    }
                    fichierb<<endl;
                 }
                fichier.close();
                fichierb.close();
            }
        }
        else cout<<"translate : impossible d'ouvrir "<<binary<<endl;
        fichier.close();
        fichierb.close();
    }
    else
    {
        string lol = "copy nul " + binary;
        system(lol.c_str());
        fichier = fopen(binary.c_str(),"wb");
        ifstream fichierb(mnt.c_str() , ios::in);
        if(fichier)
        {
            fichierb>>x>>y;
            fwrite( &x , sizeof(int) , 1 , fichier);
            fwrite( &y , sizeof(int) , 1 , fichier);
            for(int i = 0; i < 4; i++)
            {
                fichierb>>a;
                fwrite( &a , sizeof(int) , 1 , fichier);
            }
            for(int i = 0; i < x; i++)
            {
                for(int j = 0; j < y; j++)
                {
                    fichierb>>a;
                    fwrite( &a , sizeof(int) , 1 , fichier);
                }
            }
        }
        else cout<<"translate : impossible d'ouvrir "<<mnt<<endl;
        fclose(fichier);
        fichierb.close();
    }
}

bool FileManager::getNextLine( int *tab)
{

    //verifie si le fichier demande a ete trouve
    if(fichiersource)
    {
        unsigned int cols,rows;
        rows = _nblig;
        cols = _nbcol;

        //verifie si on ne demande pas une ligne exterieure au fichiersource
        if(_nblig  > _lignes)
        {
            fichiersource->read((char*)&tab[0] , (_nbcol) * sizeof(int));
            return true;
        }
        //la ligne demandee nest pas valide
        else
        {
            cout<<"ligne non presente dans le fichiersource"<<endl;
        }
    }
    //en cas dechec douverture du fichier
    else
        cout<<"echec de lecture"<<endl;
    return false;
}


void FileManager::controle(string a, string b)
{
        ifstream fichierA(a.c_str(), ios::in| ios::binary);
        ifstream fichierB(b.c_str(), ios::in| ios::binary);
        lolilol top;
        unsigned int xa, xb, ya, yb;
        xa=0; ya = 0;
        top.a=0;top.b=0;
        fichierA.read((char*)&top ,sizeof(top));
        xa=top.a;
        ya=top.b;
        fichierB.read((char*)&top ,sizeof(top));
        xb=top.a;
        yb=top.b;
        if(xa==xb && ya==yb)
        {
            float cpt = 0.0, res = 0.0;
            int tabaa[ya], tabab[ya],tabba[ya],tabbb[ya];
            fichierA.read((char*)&tabaa ,ya*sizeof(int));
            fichierB.read((char*)&tabba ,ya*sizeof(int));
            for(unsigned int i =0; i < (xa-1);i++)
            {
                fichierA.read((char*)&tabab ,ya*sizeof(int));
                fichierB.read((char*)&tabbb ,ya*sizeof(int));
                for(unsigned int j =0; j < (ya-1);j++)
                {
                    cpt+=2;
                    if((tabaa[j] == tabaa[j+1] && tabba[j] == tabba[j+1])||
                        (tabaa[j] != tabaa[j+1] && tabba[j] != tabba[j+1]))res++;
                    if((tabaa[j] == tabab[j] && tabba[j] == tabbb[j])||
                        (tabaa[j] != tabab[j] && tabba[j] != tabbb[j]))res++;
                }
                if(i != xa-2)
                {
                    for(unsigned int j = 0; j < ya;j++)
                    {
                        tabaa[j]=tabab[j];
                        tabba[j]=tabbb[j];
                    }
                }
            }
            float aff = res / cpt;
            cout<<"le resultat est juste a "<<aff*100<<"%"<<endl;
        }
        else cout<<"difference d'entete : "<<xa<<"&"<<xb<<"  "<<ya<<"&"<<yb<<endl;

        fichierA.close();
        fichierB.close();
}
